package com.example.mybank.config;

import com.example.mybank.springSecurity.CustomAuthenticationFilter;
import com.example.mybank.springSecurity.CustomizeAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDetailsService userDetailsService;

    @Autowired
    LogoutSuccessHandler logoutSuccessHandler;

    @Autowired
    AuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    AuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    CustomizeAuthenticationEntryPoint authenticationEntryPoint;


    @Bean
    public PasswordEncoder passwordEncoder(){
        // 使用BCrypt加密密码
        return NoOpPasswordEncoder.getInstance();
//        return new BCryptPasswordEncoder();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .csrf().disable()
        ;
        //
        http.authorizeRequests()
            .antMatchers(
                    "/druid/**",
                    "/users/register",
                    "/login","/logout",
                    "/users/registerByUsername/*",
                    "/product/get/*").permitAll()
            .antMatchers(
                "/account/users/*",
                "/product/time/*",
                "/product/buyable",
//                "/product/get/*",
                "/orders/account/*",
                "/orders/users/*",
                "/statement/account/*",
                "/statement/users/*",
                "/schedule/user/*",
                "/debit/account/*",
                "/debit/user/*",
                "/buycount/users/*",
                "/buycount/mix/**"
                    ).authenticated()
            .antMatchers(
                "/*/all/**",
                "/users/registerAdmin",
                "/engine/**",
                "/buycount/**",
                "/product/engine/**",
                "/product/add"
                ).hasAuthority("admin")
            .antMatchers(
                "/account/register",
                "/product/buy/*",
                "/product/buyreal/**",
                "/schedule/add/*",
                "/schedule/cancel/*",
                "/debit/add/**"
                ).hasAuthority("users")
//            .anyRequest().permitAll()
            //登出
            .and().logout()
                .permitAll()//允许所有用户
                .logoutSuccessHandler(logoutSuccessHandler)//登出成功处理逻辑
                .deleteCookies("JSESSIONID")//登出之后删除cookie
//            //登入
            .and().formLogin()
//                .loginPage("/")
                .loginProcessingUrl("/login/form")
//                .successHandler(authenticationSuccessHandler)//登录成功处理逻辑
//                .failureHandler(authenticationFailureHandler);//登录失败处理逻辑
            .and().exceptionHandling().
            authenticationEntryPoint(authenticationEntryPoint)//匿名用户访问无权限资源时的异常处理
        ;
        http.addFilterAt(customAuthenticationFilter(),
                UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
        CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
        filter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
        filter.setAuthenticationFailureHandler(authenticationFailureHandler);
        filter.setFilterProcessesUrl("/login");

        //这句很关键，重用WebSecurityConfigurerAdapter配置的AuthenticationManager，不然要自己组装AuthenticationManager
        filter.setAuthenticationManager(authenticationManagerBean());
        return filter;
    }

}
